// process-i18n.js
const fs = require('fs');
const path = require('path');
const glob = require('glob');
const inquirer = require('inquirer');
const chalk = require('chalk');
const { parse: parseSfc } = require('@vue/compiler-sfc');
const { pinyin } = require('pinyin');

// ------------------------------
// 配置
// ------------------------------
// const basePath = 'createTask/step/taskConfig';
const basePath = 'test';
const CONFIG = {
  SRC_DIR: path.resolve(__dirname, basePath),
  LOCALES_DIR: path.resolve(__dirname, 'i18n'),
  BACKUP_DIR: path.resolve(__dirname, 'backup'),
  TMP_DIR: path.resolve(__dirname, 'processed-files'),
  DEFAULT_LANG: 'zh-CN'
};

// ------------------------------
// 工具函数
// ------------------------------
const getLineNumber = (content, index) => 
  content.slice(0, index).split('\n').length;

const generateKey = (filePath, text, context) => {
  // 获取相对于 SRC_DIR 的路径
  const relativePath = path.relative(CONFIG.SRC_DIR, filePath)
    .replace(/\.vue$/, '');  // 移除 .vue 扩展名
  
  // 将 basePath 分解为部分
  const basePathParts = basePath
    .split(/[\\/]/)
    .filter(part => part)
    .map(part => part.toLowerCase());
  
  // 分解相对路径并规范化
  const pathParts = relativePath
    .split(/[\\/]/)
    .filter(part => part)
    .map(part => part.toLowerCase());
  
  // 生成拼音代码
  const pinyinCode = pinyin(text, { 
    style: pinyin.STYLE_FIRST_LETTER,
    heteronym: false 
  }).flat().join('').toLowerCase();

  const contextMap = {
    header: 'header',
    placeholder: 'placeholder',
    title: 'title',
    button: 'button',
    text: 'text',
    label: 'label',
    name: 'name',
    content: 'content',
    message: 'message',
    okText: 'okText',
    cancelText: 'cancelText'
  };

  // 组合完整的key路径，包含 basePath
  return [...basePathParts, ...pathParts, `${contextMap[context]}_${pinyinCode}`].join('.');
};

const nestTranslations = (flatTranslations) => {
  const result = {};
  Object.entries(flatTranslations).forEach(([key, value]) => {
    const keys = key.split('.')
      .filter(k => k !== ''); // 过滤掉空字符串
    
    let current = result;
    keys.slice(0, -1).forEach(k => {
      current[k] = current[k] || {};
      current = current[k];
    });
    current[keys.pop()] = value;
  });
  return result;
};

// ------------------------------
// 核心处理逻辑（添加防御性检查）
// ------------------------------
const processText = async (text, filePath, line, context) => {
  const keyRecommend = generateKey(filePath, text, context);
  
  const { key, confirm } = await inquirer.prompt([{
    type: 'input',
    name: 'key',
    message: [
      `${chalk.yellow('[发现文本]')} ${text}`,
      `位置: ${chalk.cyan(path.relative(CONFIG.SRC_DIR, filePath))}:${line}`,
      `推荐键名: ${chalk.green(keyRecommend)}`,
      '输入自定义键名（回车使用推荐）:'
    ].join('\n'),
    default: keyRecommend
  }, {
    type: 'confirm',
    name: 'confirm',
    message: '确认替换？',
    default: true
  }]);

  return confirm ? key : null;
};

const processTemplate = async (content, filePath) => {
  const { descriptor } = parseSfc(content);
  if (!descriptor?.template?.content) return { content, translations: {} };

  let newContent = content;
  const translations = {};
  const templateContent = descriptor.template.content;

  // 处理属性中的中文
  const attrMatches = [];
  newContent = newContent.replace(
    /(\bheader|placeholder|title|label|name|content|okText|cancelText|message)=["']([\u4e00-\u9fa5]+)["']/g,
    (match, attr, text) => {
      attrMatches.push({ match, attr, text });
      return match;
    }
  );

  // 处理数组/对象中的中文标签
  const labelMatches = [];
  newContent = newContent.replace(
    /(label|name|title|content|message):\s*["']([\u4e00-\u9fa5]+)["']/g,
    (match, key, text) => {
      labelMatches.push({ match, key, text });
      return match;
    }
  );

  // 处理纯文本内容
  const textMatches = [];
  newContent = newContent.replace(
    />([\u4e00-\u9fa5]+)</g,
    (match, text) => {
      textMatches.push({ match, text });
      return match;
    }
  );

  // 处理所有匹配项
  for (const { match, attr, text } of attrMatches.reverse()) {
    const key = await processText(text, filePath, getLineNumber(templateContent, match.index), attr);
    if (key) {
      newContent = newContent.replace(match, `:${attr}="$t('${key}')"`);
      translations[key] = text;
    }
  }

  for (const { match, key, text } of labelMatches.reverse()) {
    const i18nKey = await processText(text, filePath, getLineNumber(templateContent, match.index), key);
    if (i18nKey) {
      newContent = newContent.replace(match, `${key}: $t('${i18nKey}')`);
      translations[i18nKey] = text;
    }
  }

  for (const { match, text } of textMatches.reverse()) {
    const key = await processText(text, filePath, getLineNumber(templateContent, match.index), 'text');
    if (key) {
      newContent = newContent.replace(match, `>{{ $t('${key}') }}<`);
      translations[key] = text;
    }
  }

  return { content: newContent, translations };
};

const processScript = async (content, filePath) => {
  const { descriptor } = parseSfc(content);
  if (!descriptor?.script?.content) return { content, translations: {} };

  let newContent = content;
  const translations = {};
  const scriptContent = descriptor.script.content;

  // 处理对象中的中文
  const objectMatches = [];
  newContent = newContent.replace(
    /(label|name|title|content|message):\s*(['"`])([\u4e00-\u9fa5]+)\2/g,
    (match, key, quote, text) => {
      objectMatches.push({ match, key, quote, text });
      return match;
    }
  );

  // 处理消息提示函数中的中文
  const messageMatches = [];
  newContent = newContent.replace(
    /(message\.(success|error|info|warning))\(\s*(['"`])([\u4e00-\u9fa5][^'"]*[\u4e00-\u9fa5]|[\u4e00-\u9fa5]+)\3/g,
    (match, func, type, quote, text) => {
      messageMatches.push({ match, func, type, quote, text });
      return match;
    }
  );

  // 处理console.error等函数中的中文
  const consoleMatches = [];
  newContent = newContent.replace(
    /(console\.(log|error|warn|info))\(\s*(['"`])([\u4e00-\u9fa5][^'"]*[\u4e00-\u9fa5]|[\u4e00-\u9fa5]+)\3/g,
    (match, func, type, quote, text) => {
      consoleMatches.push({ match, func, type, quote, text });
      return match;
    }
  );

  // 处理错误信息中的中文
  const errorMatches = [];
  newContent = newContent.replace(
    /new Error\(\s*(['"`])([\u4e00-\u9fa5][^'"]*[\u4e00-\u9fa5]|[\u4e00-\u9fa5]+)\1\s*\)/g,
    (match, quote, text) => {
      errorMatches.push({ match, quote, text });
      return match;
    }
  );

  // 处理普通字符串中的中文
  const stringMatches = [];
  newContent = newContent.replace(
    /(['"`])([\u4e00-\u9fa5]+)\1/g,
    (match, quote, text) => {
      // 排除已经处理过的对象属性和消息
      if (!objectMatches.some(m => m.match === match) && 
          !messageMatches.some(m => m.match.includes(match)) &&
          !consoleMatches.some(m => m.match.includes(match)) &&
          !errorMatches.some(m => m.match.includes(match))) {
        stringMatches.push({ match, quote, text });
      }
      return match;
    }
  );

  for (const { match, key, quote, text } of objectMatches.reverse()) {
    const i18nKey = await processText(text, filePath, getLineNumber(scriptContent, match.index), key);
    if (i18nKey) {
      newContent = newContent.replace(match, `${key}: $t('${i18nKey}')`);
      translations[i18nKey] = text;
    }
  }

  for (const { match, func, type, quote, text } of messageMatches.reverse()) {
    const i18nKey = await processText(text, filePath, getLineNumber(scriptContent, match.index), 'message');
    if (i18nKey) {
      newContent = newContent.replace(match, `${func}(${quote}$t('${i18nKey}')${quote}`);
      translations[i18nKey] = text;
    }
  }

  for (const { match, func, type, quote, text } of consoleMatches.reverse()) {
    const i18nKey = await processText(text, filePath, getLineNumber(scriptContent, match.index), 'message');
    if (i18nKey) {
      newContent = newContent.replace(match, `${func}(${quote}$t('${i18nKey}')${quote}`);
      translations[i18nKey] = text;
    }
  }

  for (const { match, quote, text } of errorMatches.reverse()) {
    const i18nKey = await processText(text, filePath, getLineNumber(scriptContent, match.index), 'message');
    if (i18nKey) {
      newContent = newContent.replace(match, `new Error(${quote}$t('${i18nKey}')${quote})`);
      translations[i18nKey] = text;
    }
  }

  for (const { match, quote, text } of stringMatches.reverse()) {
    const key = await processText(text, filePath, getLineNumber(scriptContent, match.index), 'text');
    if (key) {
      newContent = newContent.replace(match, `${quote}$t('${key}')${quote}`);
      translations[key] = text;
    }
  }

  return { content: newContent, translations };
};

// ------------------------------
// 主流程
// ------------------------------
(async () => {
  try {
    console.log(chalk.yellow('正在初始化...'));
    [CONFIG.TMP_DIR, CONFIG.BACKUP_DIR, CONFIG.LOCALES_DIR].forEach(dir => {
      fs.mkdirSync(dir, { recursive: true });
    });

    const files = glob.sync(`${CONFIG.SRC_DIR}/**/*.vue`, {
      absolute: true,
      nodir: true,
      windowsPathsNoEscape: true
    });

    let allTranslations = {};
    for (const file of files) {
      console.log(chalk.cyan(`\n处理文件: ${path.relative(CONFIG.SRC_DIR, file)}`));
      
      // 复制到临时目录时保持相同的目录结构
      const relativePath = path.relative(CONFIG.SRC_DIR, file);
      const dest = path.join(CONFIG.TMP_DIR, relativePath);
      fs.mkdirSync(path.dirname(dest), { recursive: true });
      fs.copyFileSync(file, dest);

      const content = fs.readFileSync(dest, 'utf8');
      const { descriptor } = parseSfc(content);
      
      if (!descriptor) {
        console.error(chalk.red(`[跳过] 无效的Vue文件: ${file}`));
        continue;
      }

      let modifiedContent = content;
      const translations = {};

      // 处理模板
      if (descriptor.template?.content) {
        const templateResult = await processTemplate(modifiedContent, file); // 使用原始文件路径
        modifiedContent = templateResult.content;
        Object.assign(translations, templateResult.translations);
      }

      // 处理脚本
      if (descriptor.script?.content) {
        const scriptResult = await processScript(modifiedContent, file); // 使用原始文件路径
        modifiedContent = scriptResult.content;
        Object.assign(translations, scriptResult.translations);
      }

      fs.writeFileSync(dest, modifiedContent, 'utf8');
      allTranslations = { ...allTranslations, ...translations };
    }

    const nestedTranslations = nestTranslations(allTranslations);
    const jsContent = `export default ${JSON.stringify(nestedTranslations, null, 2)};\n`;
    fs.writeFileSync(
      path.join(CONFIG.LOCALES_DIR, `${CONFIG.DEFAULT_LANG}.js`),
      jsContent
    );

    console.log(chalk.green('\n翻译文件已生成:'), 
      path.relative(process.cwd(), path.join(CONFIG.LOCALES_DIR, `${CONFIG.DEFAULT_LANG}.js`)));

    const { confirm } = await inquirer.prompt([{
      type: 'confirm',
      name: 'confirm',
      message: '是否覆盖原文件？（原文件将备份至backup目录）',
      default: true
    }]);

    if (confirm) {
      glob.sync(`${CONFIG.TMP_DIR}/**/*.vue`).forEach(tempFile => {
        const target = path.join(CONFIG.SRC_DIR, path.relative(CONFIG.TMP_DIR, tempFile));
        const backupPath = path.join(CONFIG.BACKUP_DIR, path.relative(CONFIG.SRC_DIR, target));
        fs.mkdirSync(path.dirname(backupPath), { recursive: true });
        fs.copyFileSync(target, backupPath);
        fs.copyFileSync(tempFile, target);
        console.log(chalk.green('已覆盖:'), path.relative(CONFIG.SRC_DIR, target));
      });
    }

    console.log(chalk.green('\n处理完成！'));
  } catch (err) {
    console.error(chalk.red('运行出错:'), err);
  } finally {
    fs.rmSync(CONFIG.TMP_DIR, { recursive: true, force: true });
  }
})();